<template>
  <TableWidget v-if="hasMenu" ref="menuTable" :pagination="pagination" :columns="columns" :load="loadData"
               :has-select="true" :hide-pageable="true" style="flex: 1"
               :show-zebra="true" :show-column="true" :show-refresh="false">
    <template v-slot:toolHeader>
      <TableSearchWidget ref="refSearch" :search="searchForms">
        <template v-slot:searchTail>
          <div style="display: flex; flex-direction: row;justify-content: center">
            <el-button icon="search" plain round style="padding: 0 20px;" @click="searchData"/>
            <el-button type="primary" @click="save" style="margin: 0 8px 0 24px;">
              保存
            </el-button>
            <el-button @click="cancel" style="margin: 0 8px 0 24px;">
              取消
            </el-button>
            <div v-if="props.comment" style="display: flex;align-items: center;margin-left: 32px;color: #6b66d4;">
              <el-icon color="#6b66d4" style="margin-right: 2px;">
                <QuestionFilled/>
              </el-icon>
              {{ props.comment }}
            </div>
          </div>
        </template>
      </TableSearchWidget>
    </template>
    <template v-slot:actionBefore>
      <slot name="actionBefore"/>
    </template>
  </TableWidget>
  <div v-else style="display: flex; flex-direction: column; align-items: center; ">
    <div style="margin: 32px 0 16px 0; color: #252a2f">
      当前平台还未分配任何菜单，请点击下方按钮分配菜单。
    </div>
    <div style="display: flex; flex-direction: row;">
        <el-button class="assign-btn" type="primary" :icon="Plus" plain text @click="onAssignMenu">
          分配菜单
        </el-button>
        <el-button class="assign-btn" plain :icon="Refresh" text @click="refresh">
          刷新
        </el-button>
      </div>
  </div>
</template>

<script setup lang="ts">

import {ref, toRaw} from "vue";
import {Plus, QuestionFilled, Refresh} from "@element-plus/icons-vue";
import {loadAssetLevel} from "@/apis/sop";
import TableWidget from "@/widget/TableWidget.vue";
import TableSearchWidget from "@/widget/TableSearchWidget.vue";
import {useLoadAssign} from "@/utils/sop/UseLoadAssign";
import {useActiveMenu} from "@/utils/UseActiveMenu";
import {msgError, msgInfo} from "@/utils/InfoUtil";
import {useRouter} from "vue-router";
import {useStore} from "@/stores";
import {TYPES} from "@/stores/conf";

const refSearch = ref();
const menuTable = ref();
const hasMenu = ref();
const router = useRouter();

const props = withDefaults(defineProps<{
  entry: any,
  comment?: string,
}>(), {});

const store = useStore();
const holdMenus = ref();

const { load, assign } = useLoadAssign(props.entry);
const {updateActiveMenu} = useActiveMenu('platform');

const pagination = ref({
  current: 1,
  pageSize: 20,
  total: 0,
});

const searchForms = ref([
  {
    type: 'input',
    name: 'name',
    label: `菜单名称`,
    size: 'default',
    placeholder: `请输入菜单名称`,
    clearable: true,
    defValue: '',
  },
]);

const columns = ref([
  {
    id: 'id',
    name: '标识',
    hideCol: true,
    show: false,
  },
  {
    id: 'name',
    name: '菜单名称',
    show: true,
  },
  {
    id: 'code',
    name: '菜单码',
    show: true,
  },
  {
    id: 'componentUrl',
    name: '组件地址',
    show: false,
  },
  {
    id: 'routeUrl',
    name: '路由地址',
    show: false,
  },
  {
    id: 'state',
    name: '状态',
    show: true,
    tag: 'true',
    type: 'select',
    tagType: (tag: number) => {
      return tag === 1 ? 'success' : 'danger';
    },
    tagText: (tag: number) => {
      return tag === 1 ? '启用' : '禁用';
    },
    options: [
      {
        value: 1,
        label: '启用'
      },
      {
        value: 2,
        label: '禁用'
      }
    ]
  },
  {
    id: 'createTime',
    name: '创建时间',
    show: true,
  },
]);

const getTargetId = () => {
  return '';
}

const findSelections = (menus: any, rows: any, ret: any) => {
  menus.forEach((item: any) => {
    if (rows.find((it: any) => it.id === item.id)) {
      ret.push(item);
    }
    if (item.children) {
      findSelections(item.children, rows, ret);
    }
  })
}

const refreshHoldMenu = async (menus: any) => {
  const params: any = {
    current: 1,
    pageSize: 9999,
  };
  const selMenus = await load(getTargetId(), params, 'MENU');
  holdMenus.value = [];

  if (selMenus && selMenus.code === 0) {
    const menuData = toRaw(menus);
    findSelections(menuData, toRaw(selMenus.data.data), holdMenus.value);
  }

  return selMenus;
}

const loadData = async (params: any) => {
  const platform: any = store.getCurrentPlatform();
  const result = await loadAssetLevel({
    server: props.entry.server,
    targetId: platform.id,
    assetType: TYPES.MENU,
    ...params,
  });

  if (result && result.code === 0 && result.data) {
    hasMenu.value = true;
    const holdResult = await refreshHoldMenu(result.data.data);
    if (holdResult && holdResult.code === 0) {
      menuTable.value?.setSelectItems(toRaw(holdMenus.value));
      return result;
    }
  } else {
    hasMenu.value = false;
  }
}

const onAssignMenu = () => {
  const path = '/platform/assets/menus/';
  router.push({
    path: path
  });
  updateActiveMenu(path);
}

const getSelectItems = () => {
  return toRaw(menuTable.value.getSelectItems());
}

const computeSaveItems = () => {
  const selItems = getSelectItems();
  if (holdMenus.value && holdMenus.value.length > 0) {
    return selItems.filter((item: any) => {
      return !holdMenus.value.find((h: any) => h.id === item.id);
    })
  } else {
    return selItems;
  }
}

const save = async () => {
  const selItems = getSelectItems() || [];
  const items = computeSaveItems();
  const result = await assign(selItems, 'MENU');

  if (result && result.code === 0) {
    msgInfo(`分配${tag.value}成功！`);
    await refreshHoldMenu();
  } else {
    msgError(`分配${tag.value}失败！`);
  }
}

const cancel = () => {
  if (holdMenus.value) {
    menuTable.value?.setSelection(holdMenus.value);
  }
}

const refreshData = async (params: any) => {
  await menuTable.value?.refreshData({
    ...params,
    ...refSearch.value?.getSearchParams()
  });
}

const refresh = async () => {
  if (hasMenu.value) {
    await searchData();
  } else {
    hasMenu.value = true;
    await searchData();
  }
}

const searchData = async () => {
  await refreshData({});
}

defineExpose({
  refresh,
})

</script>

<style scoped>
.el-form-item-class .el-form-item__label {
  font-size: 12px;
}

.assign-btn {
  margin: 16px 0;
}

</style>
